package com.bysj.sausys.service.impl;

import com.bysj.sausys.beans.PageQuery;
import com.bysj.sausys.beans.PageResult;
import com.bysj.sausys.beans.Pagination;
import com.bysj.sausys.beans.SubmitTaskBean;
import com.bysj.sausys.common.AssConst;
import com.bysj.sausys.common.WorkFlowConst;
import com.bysj.sausys.dao.SysAssCancelMapper;
import com.bysj.sausys.exception.ParamException;
import com.bysj.sausys.model.SysAss;
import com.bysj.sausys.model.SysAssCancel;
import com.bysj.sausys.service.ISysAssCancelService;
import com.bysj.sausys.service.ISysAssService;
import com.bysj.sausys.service.ISysUserService;
import com.bysj.sausys.service.ISysWorkFlowService;
import com.bysj.sausys.util.ObjectUtils;
import com.bysj.sausys.util.PropertiesUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 社团注销申请Service
 *
 * @author WangZK
 */
@Service("sysAssCancelService")
public class SysAssCancelServiceImpl implements ISysAssCancelService {

    @Resource
    private SysAssCancelMapper sysAssCancelMapper;
    @Resource
    private ISysAssService sysAssService;
    @Resource
    private ISysWorkFlowService sysWorkFlowService;
    @Resource
    private ISysUserService sysUserService;

    /**
     * 保存社团注销申请，不能对同个社团提交相同的申请
     *
     * @param sysAssCancel
     * @param username
     */
    @Override
    public void save(SysAssCancel sysAssCancel, String username) {
        if (sysAssCancel.getAssId() == null) {
            throw new ParamException("请选择您需要注销的社团");
        }
        SysAss sysAss = sysAssService.findById(sysAssCancel.getAssId());
        if (sysAss == null) {
            throw new ParamException("所选择的社团不存在，请重新选择您需要注销的社团");
        }
        if (!AssConst.ENROLL.getCode().equals(sysAss.getStatus())) {
            throw new ParamException("您所选择的社团已为注销状态，请重新选择");
        }
        //判断是否已经存在没有审核完成的注销申请单
        if (checkAssCancelExist(sysAssCancel.getId(), sysAssCancel.getAssId())) {
            throw new ParamException("社团注销申请已存在，保存失败");
        }

        sysAssCancel.setInsertMan(username);
        sysAssCancel.setInsertTime(new Date());

        sysAssCancelMapper.insertSelective(sysAssCancel);
    }

    /**
     * 判断社团注销申请单是否已存在
     */
    private boolean checkAssCancelExist(Integer id, Integer assId) {
        return sysAssCancelMapper.countByAssIdAndAuditStatus(id, assId, AssConst.ASS_CANCEL_AUDIT_NOT_PASS.getCode()) > 0;
    }

    /**
     * 根据id获取注销申请单
     *
     * @param id
     * @return
     */
    @Override
    public SysAssCancel findById(int id) {
        return sysAssCancelMapper.selectByPrimaryKey(id);
    }

    /**
     * 获取注销申请单列表
     *
     * @param pageQuery
     * @return
     */
    @Override
    public PageResult<SysAssCancel> getPage(PageQuery pageQuery) {
        int count = sysAssCancelMapper.count();
        if (count > 0) {
            List<SysAssCancel> sysAssCancelList = sysAssCancelMapper.getPage(pageQuery);
            PageResult<SysAssCancel> result = new PageResult<>();
            result.setList(sysAssCancelList);
            Pagination pagination = new Pagination();
            pagination.setTotal(count);
            pagination.setPageSize(pageQuery.getPageSize());
            pagination.setCurrentPage(pageQuery.getPageNo());
            result.setPagination(pagination);
            return result;
        }
        return new PageResult<>();
    }

    /**
     * 更新社团注销申请
     *
     * @param sysAssCancel
     * @param username
     */
    @Override
    public void update(SysAssCancel sysAssCancel, String username) {
        SysAssCancel before = sysAssCancelMapper.selectByPrimaryKey(sysAssCancel.getId());
        if (before == null) {
            throw new ParamException("待更新的社团注销申请不存在");
        }
        if (AssConst.NON_EDITABLE.getCode().equals(before.getEditStatus())) {
            throw new ParamException("社团注销申请单为不可编辑状态，编辑失败");
        }
        if (sysAssCancel.getAssId() == null) {
            throw new ParamException("请选择您需要注销的社团");
        }

        SysAss sysAss = sysAssService.findById(sysAssCancel.getAssId());
        if (sysAss == null) {
            throw new ParamException("所选择的社团不存在，请重新选择您需要注销的社团");
        }
        if (!AssConst.ENROLL.getCode().equals(sysAss.getStatus())) {
            throw new ParamException("您所选择的社团已为注销状态，请重新选择");
        }

        //判断是否已经存在没有审核完成的注销申请单
        if (checkAssCancelExist(sysAssCancel.getId(), sysAssCancel.getAssId())) {
            throw new ParamException("社团注销申请已存在，更新失败");
        }
        SysAssCancel after = new SysAssCancel();

        after.setId(sysAssCancel.getId());
        after.setAssId(sysAssCancel.getAssId());
        after.setCancelReasons(sysAssCancel.getCancelReasons());
        after.setAssSituation(sysAssCancel.getAssSituation());
        after.setLastupdMan(username);
        after.setLastupdTime(new Date());

        sysAssCancelMapper.updateByPrimaryKeySelective(after);
    }

    /**
     * 删除社团注销申请
     *
     * @param id
     */
    @Override
    public void delete(Integer id) {
        SysAssCancel sysAssCancel = sysAssCancelMapper.selectByPrimaryKey(id);
        if (sysAssCancel == null) {
            throw new ParamException("社团注销申请不存在，删除失败");
        }
        if (AssConst.NON_DELETING.getCode().equals(sysAssCancel.getDeleteStatus())) {
            throw new ParamException("社团注销申请单为不可删除状态，删除失败");
        }
        sysAssCancelMapper.deleteByPrimaryKey(id);
    }

    /**
     * 启动社团注销申请审批流程
     * 判断流程能否正常启动，启动流程，让启动的流程实例关联业务，更新申请单状态
     *
     * @param id
     * @param username
     */
    @Override
    public void saveStartProcess(Integer id, String username) {
        SysAssCancel sysAssCancel = sysAssCancelMapper.selectByPrimaryKey(id);
        if (sysAssCancel == null) {
            throw new ParamException("社团注销申请单不存在，启动审批流程失败");
        }
        if (!sysAssCancel.getAuditStatus().equals(AssConst.ASS_CANCEL_INIT_ENTRY.getCode())) {
            throw new ParamException("流程已经启动，不需要再次启动");
        }

        //调用工作流的service，执行启动流程实例，让启动的流程实例关联业务的操作
        //1.通过配置文件获取流程定义的key
        String key = PropertiesUtil.getProperty(WorkFlowConst.ASS_CANCEL_KEY.getCode());
        //2.设置字符串
        String objId = sysAssCancel.getClass().getSimpleName() + "." + id;

        String processInstanceId = sysWorkFlowService.saveStartProcess(key, objId, username);

        if (processInstanceId == null || "".equals(processInstanceId)) {
            throw new ParamException("启动社团注销申请流程失败");
        }

        //更改社团注销申请单的状态
        Map map = new HashMap(4);
        map.put("id", id);
        map.put("deleteStatus", AssConst.NON_DELETING.getCode());
        map.put("editStatus", AssConst.NON_EDITABLE.getCode());
        map.put("auditStatus", AssConst.ASS_CANCEL_AUDITING.getCode());
        sysAssCancelMapper.updateStatus(map);
    }

    /**
     * 获取审批信息
     * 1.获取业务数据
     * 2.获取连线信息
     * 3.查询所有历史审核人的信息，帮助当前审核人完成审核
     *
     * @param taskId
     * @return
     */
    @Override
    public Map<String, Object> getAuditInfo(String taskId) {
        // 获取连线信息和历史审核人信息
        Map<String, Object> map = sysWorkFlowService.getAuditInfo(taskId);

        /**
         * 获取业务数据
         * 1.获取数据id
         * 2.根据id获取业务数据
         */
        int id = sysWorkFlowService.getBusinessIdByTaskId(taskId);
        SysAssCancel sysAssCancel = sysAssCancelMapper.selectByPrimaryKey(id);
        if (sysAssCancel == null) {
            throw new ParamException("获取社团注销申请单失败");
        }
        try {
            Map objectMap = ObjectUtils.objectToMap(sysAssCancel);
            objectMap.remove("insertTime");
            objectMap.remove("insertMan");
            objectMap.remove("lastupdTime");
            objectMap.remove("lastupdMan");

            map.put("businessData", objectMap);
            map.put("taskId", taskId);

            return map;
        } catch (IllegalAccessException e) {
            throw new ParamException("获取社团注销申请单失败");
        }
    }

    /**
     * 完成任务
     *
     * @param submitTaskBean
     * @param username
     */
    @Override
    public void saveSubmitTask(SubmitTaskBean submitTaskBean, String username) {
        //调用工作流封装好的方法
        String processInstanceId = sysWorkFlowService.saveSubmitTask(submitTaskBean, username, new HashMap(4));

        //判断是否需要更改申请表状态
        if (sysWorkFlowService.checkProcessIsEnd(processInstanceId)) {
            Map map = new HashMap(4);
            map.put("id", submitTaskBean.getId());
            map.put("deleteStatus", AssConst.DELETING.getCode());
            map.put("editStatus", AssConst.NON_EDITABLE.getCode());
            sysAssCancelMapper.updateStatus(map);
        }
    }

    /**
     * 获取历史批注信息
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getHisComment(Integer id) {
        SysAssCancel sysAssCancel = sysAssCancelMapper.selectByPrimaryKey(id);
        String objId = sysAssCancel.getClass().getSimpleName() + "." + id;

        Map<String, Object> map = sysWorkFlowService.findCommentByObjId(objId);
        map.put("businessData", sysAssCancel);
        return map;
    }

    /**
     * 修改社团注销申请的状态
     *
     * @param map
     */
    @Override
    public void updateStatus(Map map) {
        sysAssCancelMapper.updateStatus(map);
    }

    /**
     * @param map
     * @param sysAssCancel
     */
    @Override
    public void auditPass(Map map, SysAssCancel sysAssCancel) {
        sysAssCancelMapper.updateStatus(map);
        sysUserService.updateStatusByAssId(sysAssCancel.getAssId(), sysAssCancel.getInsertMan());
        sysAssService.updateStatus(sysAssCancel.getAssId(), sysAssCancel.getInsertMan());
    }
}
